/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.formmetadata.metadataanalysis;

import com.inspur.edp.web.common.JITEngineConstants;
import com.inspur.edp.web.common.environment.ExecuteEnvironment;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.io.NodeJsCommandResult;
import com.inspur.edp.web.common.io.NodejsFunctionUtility;
import com.inspur.edp.web.common.logger.WebLogger;
import com.inspur.edp.web.common.utility.CommandLineUtility;
import com.inspur.edp.web.common.utility.StringUtility;
import com.inspur.edp.web.formmetadata.metadata.formdom.FormDOM;
import com.inspur.edp.web.formmetadata.metadatamanager.CommandServiceManager;
import com.inspur.edp.web.formmetadata.resolver.ResolveFormMetadataItem;
import org.apache.commons.io.FilenameUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 命令服务解析
 *
 * @author noah
 */
public class CommandServiceAnalysis {
    /**
     * 解析表单元数据中的命令服务
     *
     * @param json
     * @param path
     * @param targetFormServiceBasePath
     * @param targetStorageBasePath
     * @param resolveFormMetadataItem
     */
    public static void resolveCommandService(FormDOM json, String path, String targetFormServiceBasePath, String targetStorageBasePath, ResolveFormMetadataItem resolveFormMetadataItem) {
        if (json != null && json.getModule() != null && json.getModule().getServiceRefs() != null && json.getModule().getServiceRefs().size() > 0) {
            String formCode = json.getModule().getCode();

            String destDirectory = FileUtility.combine(targetFormServiceBasePath, formCode.toLowerCase(), "services");
            String directory = destDirectory.replace("/", FileUtility.DIRECTORY_SEPARATOR_CHAR).replace("\\", FileUtility.DIRECTORY_SEPARATOR_CHAR);

            HashMap<String, String> serviceFileList = new HashMap<>(16);
            for (HashMap<String, Object> o : json.getModule().getServiceRefs()) {
                if ("0".equals(o.get("isCommon").toString())) {
                    String fileName = FileUtility.getFileName(o.get("path").toString());
                    String contents = CommandServiceManager.getTypescriptFileContent(path, "", o, ExecuteEnvironment.Design, false);
                    if (StringUtility.isNullOrEmpty(contents)) {
                        return;
                    }

                    if (!FileUtility.exists(destDirectory)) {
                        FileUtility.createDirectory(destDirectory);
                    }

                    FileUtility.writeFile(directory, fileName.toLowerCase(), contents);

                    serviceFileList.put(fileName.toLowerCase(), directory);
                }
            }

            if (resolveFormMetadataItem.getCalculateIsDynamicForm()) {
                // 进行自定义service的解析编译
                buildCustomService(json, directory, serviceFileList, resolveFormMetadataItem);

                // 拷贝对应生成物
                String sourceBuildPath = FileUtility.combine(directory, JITEngineConstants.DistRollupPathName);
                if (FileUtility.exists(sourceBuildPath)) {
                    String customJsDeployToFormFolder = FileUtility.combine(targetStorageBasePath, "dynamicjs");
                    if (FileUtility.exists(customJsDeployToFormFolder)) {
                        FileUtility.forceDelete(customJsDeployToFormFolder);
                    }
                    // 将dist-rollup 拷贝
                    FileUtility.copyFolder(sourceBuildPath, customJsDeployToFormFolder);
                }

            }
        }
    }

    /**
     * 自定义service的解析编译
     *
     * @param json
     * @param directory
     * @param serviceFileList
     * @param resolveFormMetadataItem
     */
    private static void buildCustomService(FormDOM json, String directory, HashMap<String, String> serviceFileList, ResolveFormMetadataItem resolveFormMetadataItem) {
        StringBuilder sbIndexContent = new StringBuilder();
        boolean hasWriteTsConfigJsonFile = false;
        boolean isJieXiForm = resolveFormMetadataItem.getCalculateIsDynamicForm();
        for (Map.Entry item : serviceFileList.entrySet()) {
            if (!hasWriteTsConfigJsonFile && isJieXiForm) {
                String tsConfigJsonContent = TsBuildConfigJsonGenerator.getTsConfigJsonContent();
                FileUtility.writeFile((String) item.getValue(), "tsconfig.json", tsConfigJsonContent);
                hasWriteTsConfigJsonFile = true;
            }
            // 如果是解析型
            if (isJieXiForm) {
                // 执行rollup打包
                String fileNameWithoutExtension = FilenameUtils.getBaseName((String) item.getKey());
                sbIndexContent.append("export * from './").append(fileNameWithoutExtension).append("';");
            }
        }

        // 执行tsc
        if (isJieXiForm && !serviceFileList.isEmpty()) {
            NodeJsCommandResult tscCommandResult = NodejsFunctionUtility.getTscCommandInServer(false);
            // "npx";
            String args = "cd " + directory + " && " + tscCommandResult.getNodeJsCommand();

            args += "  --build tsconfig.json ";
            String tscBuildResult = CommandLineUtility.runCommand(args);
            if (!StringUtility.isNullOrEmpty(tscBuildResult)) {
                WebLogger.Instance.info(tscBuildResult, CommandServiceAnalysis.class.getName());
            }

            String rollupPath = FileUtility.combine(directory, "dist-tsc");

            NodeJsCommandResult rollupCommandResult = NodejsFunctionUtility.getRollupCommandInServer(false);
            // 对每个js文件进行打包
            for (Map.Entry item : serviceFileList.entrySet()) {
                String fileNameWithoutExtension = FilenameUtils.getBaseName((String) item.getKey());
                String rollupCommand = "cd " + rollupPath + " &&  " + rollupCommandResult.getNodeJsCommand();
                rollupCommand += "  -f system   ";
                rollupCommand += "-i " + fileNameWithoutExtension + ".js  ";
                rollupCommand += "-o ../dist-rollup/" + fileNameWithoutExtension + ".js";
                String rollupBuildResult = CommandLineUtility.runCommand(rollupCommand);
                if (!StringUtility.isNullOrEmpty(rollupBuildResult)) {
                    WebLogger.Instance.info(rollupBuildResult, CommandServiceAnalysis.class.getName());
                }
            }
            // 暂时屏蔽打包 使用分散的脚本
            if (false) {
                String rollupCommand = "cd " + rollupPath + " &&  " + rollupCommandResult.getNodeJsCommand();
                rollupCommand += " -f system   ";
                rollupCommand += "-i " + "index.js  ";
                rollupCommand += "-o ../dist-rollup/" + "custom.service.js";
                String rollupBuildResult = CommandLineUtility.runCommand(rollupCommand);
                if (!StringUtility.isNullOrEmpty(rollupBuildResult)) {
                    WebLogger.Instance.info(rollupBuildResult, CommandServiceAnalysis.class.getName());
                }
            }
        }
    }

    public static void resolveCommandService(FormDOM json, String path, String targetStoragePath,
                                             String webDevPath, ExecuteEnvironment executeEnvironment, boolean isUpdradeTool) {

        if (json != null && json.getModule() != null && json.getModule().getServiceRefs() != null
                && json.getModule().getServiceRefs().size() > 0) {
            String code = json.getModule().getCode();
            for (HashMap<String, Object> serviceRefsObject : json.getModule().getServiceRefs()) {
                if (serviceRefsObject.get("isCommon").toString().equals("0")) {
                    String fileName = FileUtility.getFileName(serviceRefsObject.get("path").toString());

                    String contents = CommandServiceManager.getTypescriptFileContent(path, webDevPath, serviceRefsObject, executeEnvironment, isUpdradeTool);
                    if (StringUtility.isNullOrEmpty(contents)) {
                        return;
                    }
                    String destDirectory = FileUtility.combine(targetStoragePath, code.toLowerCase(), "services");
                    boolean isPathExists = FileUtility.exists(destDirectory);
                    if (!isPathExists) {
                        FileUtility.createDirectory(destDirectory);
                    }

                    FileUtility.writeFile(destDirectory, fileName.toLowerCase(), contents);

                }
            }
        }
    }
}
